﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using DbSharp.Framework.Common;

namespace DbSharp.Framework.Assertion
{
    [Obfuscation]
    public enum AssertPrimitiveType
    {
        NotCareResultset,
        
        StrictEqual,

        SetEqual,
        IsSupersetOf,
        IsSubsetOf,
        IsProperSupersetOf,
        IsProperSubsetOf, 
        Overlaps,

        DecimalElementIsInNumAxis, // InIntervalOfNumAxis is another obsolete alias
        DecimalElementIsEqual,
        DecimalElementIsGreater, 
        DecimalElementIsGreaterOrEqual,
        DecimalElementIsLess,
        DecimalElementIsLessOrEqual,

        RecordCountIsEqual, //RecordCountEqual  is another obsolete alias
        RecordCountIsInNumAxis,  // RecordCountInIntervalOfNumAxis is another obsolete alias
        RecordCountIsGreater,
        RecordCountIsGreaterOrEqual,
        RecordCountIsLess,
        RecordCountIsLessOrEqual 
    }

    [Obfuscation]
    public class AssertionType
    {
        public AssertPrimitiveType PrimitiveType { get; set; }
        public bool WithLogicNotMark { get; set; }

        public override string ToString()
        {
            string assertionText = PrimitiveType.ToString();
            if (WithLogicNotMark)
                assertionText = "!" + assertionText;
            return assertionText;
        }
    }



    static class AssertionTypeHelper
    {
        public static AssertPrimitiveType Parse(string assertionTypeText, out bool withLogicNotMark)
        {
            AssertPrimitiveType DEFAULT_ASSERT = AssertPrimitiveType.NotCareResultset;
            withLogicNotMark = false;

            if (string.IsNullOrEmpty(assertionTypeText))
                return DEFAULT_ASSERT;

            AssertPrimitiveType assertionType;
            string typeStr = assertionTypeText.Trim().ToUpper();
            withLogicNotMark = typeStr.Contains('!');
            if (withLogicNotMark)
            {
                int index = typeStr.IndexOf('!');
                if (index < typeStr.Length - 1)
                    typeStr = typeStr.Substring(index + 1);
            }
            switch (typeStr)
            {
                case "NOTCARERESULTSET":
                    {
                        if (withLogicNotMark)
                            throw new DbSharpException("NotCareResultset assertion has no corresponding not logic type.");
                        else
                            assertionType = AssertPrimitiveType.NotCareResultset;
                        break;
                    }
                case "STRICTEQUAL":
                    {
                        assertionType = AssertPrimitiveType.StrictEqual;
                        break;
                    }

                case "SETEQUAL":
                    {
                        assertionType = AssertPrimitiveType.SetEqual;
                        break;
                    }

                case "ISSUPERSETOF":
                    {
                        assertionType = AssertPrimitiveType.IsSupersetOf;
                        break;
                    }
                case "ISPROPERSUPERSETOF":
                    {
                        assertionType = AssertPrimitiveType.IsProperSupersetOf;
                        break;
                    }
                case "ISSUBSETOF":
                    {
                        assertionType = AssertPrimitiveType.IsSubsetOf;
                        break;
                    }
                case "ISPROPERSUBSETOF":
                    {
                        assertionType = AssertPrimitiveType.IsProperSubsetOf;
                        break;
                    }
                case "OVERLAPS":
                    {
                        assertionType = AssertPrimitiveType.Overlaps;
                        break;
                    }
                case "RECORDCOUNTEQUAL": //this name is obsolete
                case "RECORDCOUNTISEQUAL":
                    {
                        assertionType = AssertPrimitiveType.RecordCountIsEqual;
                        break;
                    }
                case "ININTERVALOFNUMAXIS"://this name is obsolete
                case "DECIMALELEMENTISINNUMAXIS":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsInNumAxis;
                        break;
                    }

                case "DECIMALELEMENTISEQUAL":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsEqual;
                        break;
                    }
                case "DECIMALELEMENTISGREATER":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsGreater;
                        break;
                    }
                case "DECIMALELEMENTISGREATEROREQUAL":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsGreaterOrEqual;
                        break;
                    }
                case "DECIMALELEMENTISLESS":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsLess;
                        break;
                    }
                case "DECIMALELEMENTISLESSOREQUAL":
                    {
                        assertionType = AssertPrimitiveType.DecimalElementIsLessOrEqual;
                        break;
                    }

                case "RECORDCOUNTININTERVALOFNUMAXIS": //this name is obsolete
                case "RECORDCOUNTISINNUMAXIS":
                    {
                        assertionType = AssertPrimitiveType.RecordCountIsInNumAxis;
                        break;
                    }
                default:
                    {
                        assertionType = DEFAULT_ASSERT;
                        break;
                    }

            }
            return assertionType;
        }

    }


     
}
